//
//  StatusPictureView.swift
//  weibo
//
//  Created by 张衡 on 15/8/3.
//  Copyright © 2015年 张衡. All rights reserved.
//


/**

 照片选择器
 在collectionView的cell 选中的代理方法中，发送通知，，将图片url数组和选中索引传出

 */

import UIKit
import SDWebImage


/// 选中照片通知
let ZHStatusCellSelectPictureNotification = "ZHStatusCellSelectPictureNotification"
/// URL 的 KEY
let ZHStatusCellSelectPictureURLKey = "ZHStatusCellSelectPictureURLKey"
/// IndexPath 的 KEY
let ZHStatusCellSelectPictureIndexKey = "ZHStatusCellSelectPictureIndexKey"

/// 可重用 cell 标示符
private let statusPictureViewCellID = "statusPictureViewCellID"

class StatusPictureView: UICollectionView {
    
    
    var status: Status? {
        didSet {
            sizeToFit()  // 计算大小
            // 刷新视图
            reloadData()
        }
    }
    // // 调用sizeToFit()后紧接着调用sizeThatFits， 随意可内部计算其大小，也可以把这个函数传递出去计算大小。自己的实情自己做，更好的封装
    override func sizeThatFits(size: CGSize) -> CGSize {
        return calcViewSize()
    }
    
    
    /// 计算CollectionView视图大小
    private func calcViewSize() -> CGSize {
        // 0. 准备常量
        let itemSize = CGSize(width: 90, height: 90)
        let margin: CGFloat = 10
        // 每一行最多显示的图片数量
        let rowCount = 3
        
        pictureLayout.itemSize = itemSize
        
        // 1. 根据图片数量计算视图大小
        let count = status?.pictureURLs?.count ?? 0
//        let count2 = status?.pic_urls?.count ?? 0
//        print("\(count)---\(count2)")
        
        // 1》 没有图片
        if count == 0 {
            return CGSizeZero
        }
        
        // 2> 1张图片
        if count == 1 {
            // 从SDWebImage中获取缓存图片
            let key = status?.pictureURLs![0].absoluteString
            
            let image = SDWebImageManager.sharedManager().imageCache.imageFromMemoryCacheForKey(key)
            
            // TODO: 暂时设置一个大小
            var size = CGSize(width: 160, height: 120)
            
            // 判断图像是否存在，如果不存在，后续显示的时候，SDWebImage 会再次尝试下载，但会使用自己设置默认大小显示
            if image != nil {
                size = image.size
            }
            
            // 对图形尺寸做进一步判断 (不能太窄，太宽，便于点击）
            size.width = size.width < 40 ? 40 : size.width
            size.width = size.width > UIScreen.mainScreen().bounds.width ? 150 : size.width
            
            pictureLayout.itemSize = size
            
            return size
        }
        
        // 3> 4张图片 2 * 2
        if count == 4 {
            let w = itemSize.width * 2 + margin
            
            return CGSize(width: w, height: w)
        }
        
        // 4> 其他
        /**
        2, 3
        5, 6
        7, 8, 9
        */
        // 计算行数
        let row = (count - 1) / rowCount + 1
        let w = itemSize.width * CGFloat(rowCount) + margin * CGFloat(rowCount - 1)
        let h = itemSize.height * CGFloat(row) + margin * CGFloat(row - 1)
        
        return CGSize(width: w, height: h)
    }
    

    /// 图片布局
    private let pictureLayout = UICollectionViewFlowLayout()
    
    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
        // 提示：调用父类的构造函数之前，必须给所需的本类的属性初始化，是与懒加载矛盾的
        super.init(frame: frame, collectionViewLayout: pictureLayout)
        
        backgroundColor = UIColor.clearColor()
        
        // 注册可重用 cell
        registerClass(StatusPictureViewCell.self, forCellWithReuseIdentifier: statusPictureViewCellID)
        
        // 设置代理，让自己成为自己的数据代理,开发时，如果有局部小视图，可以自己充当自己的数据源或者代理
        self.dataSource = self
        
        // 开始做点击图片后的动画专场
        self.delegate = self
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
 
}

// 在 swift 中，协议同样可以通过 extension 来写，可以将一组协议方法，放置在一起，便于代码维护和阅读！
extension StatusPictureView: UICollectionViewDataSource, UICollectionViewDelegate {
    
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        // 要传递什么内容
        // 1. URL数组
        // 2. 用户选择的 indexPath
        // 两者组合起来可以得出所选照片
        /**
        name: 通知的名字，向通知中心发送，由通知中心向所有的监听者`广播`
        object: 发生事件的时候，传递一个对象，可以是 self
        userInfo: 字典，可以随着通知发送更多的消息
        
        应用场景:
        1. 没有返回值
        2. 如果视图层次嵌套很深，通过代理逐层传递非常繁琐，可以使用通知
        3. 让对象之间解耦
        
        注意事项：
        1. 通知中心的方法是同步执行的！先执行监听方法，执行完毕后，才会执行后续的代码
        */
        
//        // 测试代码
//        let v = UIView()
//        v.backgroundColor = UIColor.lightGrayColor()
//        v.frame = cellFullScreenFrame(indexPath)
//        UIApplication.sharedApplication().keyWindow?.addSubview(v)
        // print(indexPath.item)
        NSNotificationCenter.defaultCenter().postNotificationName(ZHStatusCellSelectPictureNotification, object: self, userInfo: [ZHStatusCellSelectPictureURLKey: status!.largePictureURLs!, ZHStatusCellSelectPictureIndexKey: indexPath])
        
        // 监听方法执行完毕之后，才会被调用，证明是同步执行
        // print("执行完回来了")
    }
    
    
    /// 计算 cell 在屏幕上得坐标位置
    func cellScreenFrame(indexPath: NSIndexPath) -> CGRect {
        
        let cell = self.cellForItemAtIndexPath(indexPath)!
        // 知道 cell 在主窗口的位置，self 是 cell 的父视图，cell 的frame 是相对父视图的坐标，转化成相对主窗口的坐标
        return convertRect(cell.frame, toCoordinateSpace: UIApplication.sharedApplication().keyWindow!)
    }
    
    /// 计算 cell 在屏幕上放大到全屏后的位置
    func cellFullScreenFrame(indexPath: NSIndexPath) -> CGRect {
        // 资源是缩略图，放大之后，显示大图，两张图片的比例一样
        // 利用缩略图的宽高比计算大图位置
        // 1. 拿到缩略图
        let key = status?.pictureURLs![indexPath.item].absoluteString
        let image = SDWebImageManager.sharedManager().imageCache.imageFromDiskCacheForKey(key)
        
        // 2. 根据缩略图计算比例
        let scale = image.size.height / image.size.width
        let screenSize = UIScreen.mainScreen().bounds.size
        let height = screenSize.width * scale
        
        // 3. 考虑长短图
        var y: CGFloat = 0
        if height < screenSize.height {
            // 短图居中显示
            y = (screenSize.height - height) * 0.5
        }
        
        return CGRect(x: 0, y: y, width: screenSize.width, height: height)
    }
    
    
    
    
    
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return status?.pictureURLs?.count ?? 0
    }
    
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(statusPictureViewCellID, forIndexPath: indexPath) as! StatusPictureViewCell
        
        cell.imageURL = status!.pictureURLs![indexPath.item]
        
        
        return cell
    }
}



class StatusPictureViewCell: UICollectionViewCell {
    
    var imageURL: NSURL? {
        didSet {
            iconView.sd_setImageWithURL(imageURL!)
            
            // 根据URL的扩展名判断是否是gif 
            gifImageView.hidden = (imageURL!.absoluteString as NSString).pathExtension.lowercaseString != "gif"
        }
    }
    
    // MARK: - 构造函数
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        contentView.addSubview(iconView)
        iconView.addSubview(gifImageView)
        iconView.ff_Fill(contentView)
        gifImageView.ff_AlignInner(type: ff_AlignType.BottomRight, referView: iconView, size: nil)
    }
    
    // MARK: 懒加载控件
    private lazy var iconView: UIImageView = {
        let iv = UIImageView()
        /// 设置图片填充模式
        iv.contentMode = UIViewContentMode.ScaleAspectFill
        // 超出边界部分要剪裁掉
        iv.clipsToBounds = true
        
        
        return iv
    }()
    
    // gif图标
    private lazy var gifImageView: UIImageView = UIImageView(image: UIImage(named: "timeline_image_gif"))
}

